﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sirocco.Data.Entity;
using SiroccoTest.Common;

namespace SiroccoTest.Data.Entity
{
    [TestClass]
    public class ContactTest : BaseTest
    {
        private TestContext TestContextInstance;
        private Contact _contact;
        private const string ColSalutation = "Mr.";
        private const string ColFirstName = "John";
        private const string ColMiddleName = "Doe";
        private const string ColLastName = "Diddy";
        private Email ColEmail;
        private const string ColAddress = "john_doe@test.net";
        private const string ColSuffix = "Sfx";
        private const string UpdateText = "Update";
        private const Gender ColGender = Gender.Male;
        private static DateTime ColDateOfBirth = DateTime.MinValue;

        #region Text Context
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return TestContextInstance;
            }
            set
            {
                TestContextInstance = value;
            }
        }
        #endregion

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        #region Ctor
        /// <summary>
        /// Ctor for this test
        /// </summary>
        public ContactTest()
        {
            _contact = new Contact
            {
                Salutation = ColSalutation,
                FirstName = ColFirstName,
                LastName = ColLastName,
                Address = ColAddress,
                Suffix = ColSuffix,
                Gender = ColGender,
                DateOfBirth = ColDateOfBirth
            };
        }

        #endregion

        /// <summary>
        /// Test insert contact to database using nhibernate 
        /// </summary>
        [TestMethod]
        public void ContactTestInsert()
        {
            using (var sess = GetSession())
            using (var tx = sess.BeginTransaction())
            {
                var contact = _contact.Clone();
                var generatedId = sess.Save(contact);
                
                // Find the Contact
                var contactLoad = sess.Load<Contact>(generatedId);
                Assert.IsNotNull(contactLoad, "Contact - Contact not saved");

                tx.Commit();
            }
        }

        [TestMethod]
        public void ContactTestUpdate()
        {
            using (var sess = GetSession())
            using (var tx = sess.BeginTransaction())
            {
                var contact = _contact.Clone();
                var generatedId = sess.Save(contact);

                // Find the Contact
                var contactLoad = sess.Load<Contact>(generatedId);
                Assert.IsNotNull(contactLoad, "Contact - Contact not found");

                // Update the Contact
                contactLoad.FirstName = ColFirstName + UpdateText;
                sess.Update(contactLoad);
                
                // Find the Contact
                var contactList = sess.CreateQuery("from Contact as c where c.FirstName = ?").SetString(0, ColFirstName + UpdateText).List();
                Assert.IsTrue(contactList.Count > 0, "Update Test - No Contact Found");

                tx.Commit();
            }
        }

        [TestMethod]
        public void ContactTestDelete()
        {
            using (var sess = GetSession())
            using (var tx = sess.BeginTransaction())
            {
                var contact = _contact.Clone();
                var generatedId = sess.Save(contact);

                // Find the Contact
                var contactToDelete = sess.Load<Contact>(generatedId);
                Assert.IsNotNull(contactToDelete, "Contact - Contact not found");

                // Delete the Contact
                sess.Delete(contactToDelete);

                // Find the Contact again
                var contactList = sess.CreateQuery("from Contact as c where c.Id = ?").SetInt64(0, (long)generatedId).List();
                Assert.IsTrue(contactList.Count == 0, "Delete Test - Contact still exists and not deleted.");

                tx.Commit();
            }
        }

        [TestMethod]
        public void ContactTestInsertMultiple()
        {
            using (var sess = GetSession())
            using (var tx = sess.BeginTransaction())
            {
                var contact1 = _contact.Clone();
                var contact2 = _contact.Clone();

                // Save both the contacts
                sess.Save(contact1);
                sess.Save(contact2);

                // Find the Contact again
                var contactList = sess.CreateQuery("from Contact as c where c.Address = ?").SetString(0, _contact.Address).List();
                Assert.IsTrue(contactList.Count == 2, "Contact count is not 2");

                tx.Commit();
            }
        }
    }
}
